#include <gtest/gtest.h>
#include "backtest/backtest_engine.h"
#include "backtest/data_loader.h"
#include "strategy/simple_ma_strategy.h"
#include <memory>
#include <fstream>
#include <sstream>

class MaStrategyTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 创建测试数据
        create_test_data();
        
        // 初始化回测引擎
        engine_ = std::make_shared<BacktestEngine>();
        engine_->set_initial_balance(100000.0);  // 设置初始资金
        engine_->set_commission_rate(0.001);     // 设置手续费率0.1%
        
        // 创建并设置数据加载器
        data_loader_ = std::make_shared<CsvDataLoader>();
        data_loader_->set_data_path("tests/test_data/market_data.csv");
        engine_->set_data_loader(data_loader_);
        
        // 创建并添加策略
        strategy_ = std::make_shared<SimpleMaStrategy>(5, 20);  // 5日和20日均线
        engine_->add_strategy(strategy_);
    }

    void create_test_data() {
        std::ofstream file("tests/test_data/market_data.csv");
        file << "timestamp,symbol,open,high,low,close,volume\n";
        
        // 生成模拟的价格数据
        double price = 100.0;
        for (int i = 0; i < 100; ++i) {
            std::string timestamp = "2023-01-" + 
                                  (i < 9 ? "0" : "") + 
                                  std::to_string(i + 1) + 
                                  " 10:00:00";
            
            // 添加一些价格波动
            double change = (std::rand() % 200 - 100) / 100.0;  // -1.0到1.0的随机变化
            price += change;
            if (price < 50.0) price = 50.0;  // 设置最低价格
            
            file << timestamp << ",BTC/USDT,"
                 << price << "," 
                 << price * 1.01 << "," 
                 << price * 0.99 << "," 
                 << price << "," 
                 << 1000 + (std::rand() % 1000) << "\n";
        }
        file.close();
    }

    std::shared_ptr<BacktestEngine> engine_;
    std::shared_ptr<DataLoader> data_loader_;
    std::shared_ptr<SimpleMaStrategy> strategy_;
};

// 基本功能测试
TEST_F(MaStrategyTest, BasicFunctionality) {
    // 运行回测
    auto result = engine_->run("BTC/USDT", 
                             "2023-01-01 00:00:00", 
                             "2023-04-01 00:00:00");
    
    // 验证基本结果
    EXPECT_GT(result.total_trades, 0);
    EXPECT_GE(result.winning_trades + result.losing_trades, result.total_trades);
    EXPECT_GE(result.win_rate, 0.0);
    EXPECT_LE(result.win_rate, 1.0);
    EXPECT_GE(result.profit_factor, 0.0);
}

// 边界条件测试
TEST_F(MaStrategyTest, EdgeCases) {
    // 测试空数据
    auto result = engine_->run("BTC/USDT", 
                             "2024-01-01 00:00:00",  // 未来的日期
                             "2024-02-01 00:00:00");
    
    EXPECT_EQ(result.total_trades, 0);
    EXPECT_EQ(result.winning_trades, 0);
    EXPECT_EQ(result.losing_trades, 0);
    
    // 测试极短时间段
    result = engine_->run("BTC/USDT",
                         "2023-01-01 00:00:00",
                         "2023-01-01 00:00:01");
    
    EXPECT_EQ(result.total_trades, 0);  // 数据太少，不应该产生交易
}

// 性能测试
TEST_F(MaStrategyTest, Performance) {
    auto start = std::chrono::high_resolution_clock::now();
    
    // 运行回测
    auto result = engine_->run("BTC/USDT",
                             "2023-01-01 00:00:00",
                             "2023-04-01 00:00:00");
    
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    
    // 验证执行时间在合理范围内（例如小于1秒）
    EXPECT_LT(duration.count(), 1000);
    
    // 验证回测结果的性能指标
    EXPECT_GE(result.sharpe_ratio, -10.0);  // Sharpe比率应该在合理范围内
    EXPECT_LE(result.sharpe_ratio, 10.0);
    EXPECT_GE(result.max_drawdown, 0.0);    // 最大回撤应该是非负的
    EXPECT_LE(result.max_drawdown, 1.0);    // 最大回撤不应超过100%
}

// 策略参数敏感性测试
TEST_F(MaStrategyTest, ParameterSensitivity) {
    // 测试不同的移动平均周期
    std::vector<std::pair<int, int>> period_pairs = {
        {3, 10}, {5, 20}, {10, 30}, {20, 60}
    };
    
    std::vector<BacktestResult> results;
    for (const auto& [short_period, long_period] : period_pairs) {
        strategy_ = std::make_shared<SimpleMaStrategy>(short_period, long_period);
        engine_->add_strategy(strategy_);
        
        auto result = engine_->run("BTC/USDT",
                                 "2023-01-01 00:00:00",
                                 "2023-04-01 00:00:00");
        results.push_back(result);
        
        // 验证每组参数的结果都是有效的
        EXPECT_GT(result.total_trades, 0);
        EXPECT_GE(result.end_balance, 0.0);
    }
    
    // 验证不同参数组合产生了不同的结果
    bool has_different_results = false;
    for (size_t i = 1; i < results.size(); ++i) {
        if (results[i].total_trades != results[0].total_trades ||
            std::abs(results[i].end_balance - results[0].end_balance) > 0.01) {
            has_different_results = true;
            break;
        }
    }
    EXPECT_TRUE(has_different_results);
}